home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / cheetah.zip / MPUTZC.C < prev    next >
C/C++ Source or Header  |  1992-06-14  |  5KB  |  137 lines

  1. /* cputzc.c  -  Decoding image in ZCompact format to HRAM buffer,
  2.  *              in form of 4 planes. (for UNCHAINED mode).
  3.  *
  4.  * Uses following coding method:
  5.  *
  6.  * Line    ends by a 0, 0 (color code = 0, counter = 0)
  7.  * Picture ends by rows counter.
  8.  *
  9.  *     +7-------------------6+5----------------------0+
  10.  *     | counter (1 till 3)  |  color code (0 - 63)   |
  11.  *     +---------------------+------------------------+
  12.  * or
  13.  *     +7-6+5------------0+    +7---------------------0+
  14.  *     | 0 | color code   |    |  counter              |
  15.  *     +---+--------------+    +-----------------------+
  16.  *
  17.  * Functions:
  18.  *      MputZCompact().
  19.  *
  20.  * See Also: uputc.c, cput.c
  21.  * Portability: BORLANDC
  22.  *                                      (c) erdy 1992
  23.  * $Header: $
  24.  */
  25. #pragma inline
  26. #include "far.h"
  27. #include "vgaprefx.h"
  28. #include "vgadrv.h"
  29. #include "screen.h"
  30.  
  31. void MputZCompact(char far *image,    /* image data ptr, seg:0 points to colormap */
  32.                   int rows,           /* rows to process */
  33.                   unsigned planewidth,/* width of plane buffer, in paragraphs */
  34.                   unsigned planeintl, /* plane buffer interleaving */
  35.                   unsigned segment    /* address segment of planes buffer */
  36.                   )
  37. {
  38.         char near *index[NPLANES]; /* Reserve space for indeces */
  39.         /* This code cause compiler to produce the following instructions:
  40.          *
  41.          *  push    bp     ; save old bp
  42.          *  mov     bp,sp  ; save old sp
  43.          *  sub     sp,8   ; space for array
  44.          *
  45.          *  So bp points to itself in stack. Then we pushed ds and bp.
  46.          *
  47.          *   | old bp   |    <-- primary bp position    |
  48.          *   ------------                               | Decreasing
  49.          *   | index[0] |    <-- new bp position        | address
  50.          *   ------------                               V
  51.          *   | index[2] |
  52.          *   ------------
  53.          *   | index[3] |
  54.          *   ------------
  55.          *   | index[4] |
  56.          *   ------------
  57.          *   |   ds     |
  58.          *   ------------
  59.          *   | saved bp |    <-- sp
  60.          *   ------------
  61.          *  In order to make bp to points to array, just substract 2.
  62.          */
  63.  
  64.         /* Charge the offsets, we will use it in back order */
  65.         index[3] = 0;
  66.         index[2] = planeintl;
  67.         index[1] = index[2] + planeintl;
  68.         index[0] = index[1] + planeintl;
  69.  
  70.         /* Charge the registers */
  71.     _CX = rows;
  72.         _ES = segment;
  73.         _DX = planewidth;
  74.         asm xor di, di;        /* Start from 0 */
  75.  
  76.     asm push ds;
  77.     asm lds si, image;
  78.     asm cld;
  79.         asm push bp;               /* Save bp */
  80.         asm sub bp, sizeof(int);   /* bp now points to index[0] */
  81.     /*
  82.      * Scanline loop. CX contains nrows.
  83.      */
  84. Loop:
  85.                 asm push bp;                    /* Save starting bp */
  86.                 asm push cx;                    /* Loop counter */
  87.  
  88.                 /* Loop until EOL */
  89.         for (;;) {
  90.             asm lodsb;              /* al <- ds:[si++]; get next byte */
  91.             asm mov bl, al;         /* Save color code */
  92.  
  93.             asm rol al, 1;          /* Get counter */
  94.                         asm rol al, 1;          /* = shr al, 6 */
  95.                         asm and ax, 3;          /* ah = 0, al &= 3 */
  96.             asm jne short OKCounter;
  97.                 asm lodsb;      /* Long counter */
  98.                 if (_AL == 0) { /* End of this scanline */
  99.                     break;
  100.                 }
  101. OKCounter:
  102.             if (_BL == 0) {         /* Zero color code -> skipping */
  103.                 asm add di, ax; /* Advance the index */
  104.                 continue;
  105.             }
  106.             asm mov cx, ax;         /* Save length */
  107.             /*
  108.              * Color map table must reside at segment:0.
  109.              */
  110.                         asm and bx, 0x3F;               /* Mask off color code */
  111.                         asm mov al, [bx];               /* Map color code */
  112. Lplane:
  113.                                 asm mov di, [bp];
  114.                                 asm stosb;
  115.                                 asm mov [bp], di;
  116.                                 asm dec bp;
  117.                                 asm dec bp;
  118.                                 asm jge C1;
  119.                                         asm add bp, NPLANES*sizeof(void near *);
  120. C1:
  121.                                 asm loop Lplane;
  122.             continue;
  123.         }
  124.                 asm mov ax, es;
  125.                 asm add ax, dx;  /* Advance es to next row */
  126.                 asm mov es, ax;
  127.                 asm xor di, di;
  128.  
  129.                 asm pop cx;
  130.                 asm pop di;
  131.  
  132.         asm loop Loop;
  133.  
  134.         asm pop bp;
  135.     asm pop ds;
  136.     return;
  137. }